﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;

namespace gt.rediscachemanager.Entry
{
    public class RedisMessageWrapper<T, TResult>
    {
        private RedisKey m_key;
        private TResult m_result;
        private T m_value;
        private TimeSpan? m_expiredTime;
        private When m_when;
        private ScanMessage m_scan;

        public RedisKey Key
        {
            get { return this.m_key; }
            set { this.m_key = value; }
        }
        public T Value
        {
            get { return this.m_value; }
            set { this.m_value = value; }
        }
        public TResult Result
        {
            get { return this.m_result; }
            set { this.m_result = value; }
        }
        public TimeSpan? ExpiredTime
        {
            get { return this.m_expiredTime; }
            set { this.m_expiredTime = value; }
        }
        public When When
        {
            get { return this.m_when; }
            set { this.m_when = value; }
        }
        public ScanMessage Scan
        {
            get { return this.m_scan; }
            set { this.m_scan = value; }
        }

        public virtual CommandFlags GetCommandFlags(RedisCommand command)
        {
            switch (command)
            {
                case RedisCommand.HashExist:
                case RedisCommand.HashGet:
                case RedisCommand.HashGetAll:
                case RedisCommand.HashGetByArray:
                case RedisCommand.HashLength:
                case RedisCommand.HashValues:
                case RedisCommand.HashFields:
                case RedisCommand.KeyExists:
                case RedisCommand.ListGetByIndex:
                case RedisCommand.ListLength:
                case RedisCommand.ListRange:
                case RedisCommand.StringGet:
                case RedisCommand.SetLength:
                case RedisCommand.SetMembers:
                case RedisCommand.SetRandomMember:
                case RedisCommand.SetRandomMembers:
                case RedisCommand.SetContains:
                case RedisCommand.SortedSetLength:
                case RedisCommand.SortedSetRangeByRank:
                case RedisCommand.SortedSetRangeByScore:
                case RedisCommand.StringBitCount:
                case RedisCommand.StringBitPosition:
                case RedisCommand.StringGetBit:
                case RedisCommand.HyperLogLogLength:
                case RedisCommand.HyperLogLogLengthArray:
                    return CommandFlags.PreferSlave;
                default:
                    return CommandFlags.DemandMaster;
            }
        }
    }

    public class ScanMessage
    {
        public ScanMessage(string fieldPattern, int pageSize, long cursor, int pageOffset)
        {
            this.FieldPattern = fieldPattern;
            this.Cursor = cursor;
            this.PageSize = pageSize;
            this.PageOffset = pageOffset;
        }
        public string FieldPattern { get; set; }
        public int PageSize { get; set; }

        public long Cursor { get; set; }
        public int PageOffset { get; set; }
    }

    #region String

    public class StringSetMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public StringSetMessage(RedisKey key, RedisValue value)
            : this(key, value, null, When.Always)
        { }
        public StringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiredTime)
            : this(key, value, expiredTime, When.Always)
        { }
        public StringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiredTime, When when)
        {
            this.Key = key;
            this.Value = value;
            this.ExpiredTime = expiredTime;
            this.When = when;
        }
    }
    public class StringAppendMessage : RedisMessageWrapper<RedisValue, long>
    {
        public StringAppendMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class StringSetArrayMessage : RedisMessageWrapper<KeyValuePair<RedisKey, RedisValue>[], bool>
    {
        public StringSetArrayMessage(KeyValuePair<RedisKey, RedisValue>[] kvps, When when)
        {
            this.Key = kvps.First().Key;
            this.Value = kvps;
            this.When = when;
        }
    }
    public class StringGetSetMessage : RedisMessageWrapper<RedisValue, RedisValue>
    {
        public StringGetSetMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class StringGetMessage : RedisMessageWrapper<RedisValue, RedisValue>
    {
        public StringGetMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class StringIncrementMessage : RedisMessageWrapper<long, long>
    {
        public StringIncrementMessage(RedisKey key, long value)
        {
            this.Key = key;
            this.Value = value;
        }
    }

    #endregion

    #region Key

    public class KeyExistsMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public KeyExistsMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class KeyRemoveMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public KeyRemoveMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class KeyRemoveArrayMessage : RedisMessageWrapper<RedisKey[], long>
    {
        public KeyRemoveArrayMessage(RedisKey key, RedisKey[] value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class KeyExpiredMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public KeyExpiredMessage(RedisKey key, TimeSpan? expiredTime)
        {
            this.Key = key;
            this.ExpiredTime = expiredTime;
        }
    }
    public class KeyTimeToLiveMessage : RedisMessageWrapper<RedisValue, TimeSpan?>
    {
        public KeyTimeToLiveMessage(RedisKey key)
        {
            this.Key = key;
        }
    }


    #endregion

    #region Hash

    public class HashGetMessage : RedisMessageWrapper<RedisValue, RedisValue>
    {
        public HashGetMessage(RedisKey key, RedisValue field)
        {
            this.Key = key;
            this.Value = field;
        }
    }
    public class HashGetByArrayMessage : RedisMessageWrapper<RedisValue[], RedisValue[]>
    {
        public HashGetByArrayMessage(RedisKey key, RedisValue[] field)
        {
            this.Key = key;
            this.Value = field;
        }
    }
    public class HashGetAllMessage : RedisMessageWrapper<RedisValue, HashEntry[]>
    {
        public HashGetAllMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class HashExistsMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public HashExistsMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }

    public class HashSetMessage : RedisMessageWrapper<HashEntry, bool>
    {
        public HashSetMessage()
        { }
        public HashSetMessage(RedisKey key, HashEntry HashEntry)
            : this(key, HashEntry, When.Always)
        {
        }
        public HashSetMessage(RedisKey key, HashEntry HashEntry, When when)
        {
            this.Key = key;
            this.Value = HashEntry;
            this.When = when;
        }
    }
    public class HashSetArrayMessage : RedisMessageWrapper<HashEntry[], bool>
    {
        public HashSetArrayMessage(RedisKey key, HashEntry[] HashEntry)
        {
            this.Key = key;
            this.Value = HashEntry;
        }
    }
    public class HashRemoveMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public HashRemoveMessage(RedisKey key, RedisValue field)
        {
            this.Key = key;
            this.Value = field;
        }
    }
    public class HashRemoveArrayMessage : RedisMessageWrapper<RedisValue[], long>
    {
        public HashRemoveArrayMessage(RedisKey key, RedisValue[] fields)
        {
            this.Key = key;
            this.Value = fields;
        }
    }
    public class HashScanMessage : RedisMessageWrapper<RedisValue, IEnumerable<HashEntry>>
    {
        public HashScanMessage(RedisKey key, RedisValue fieldPattern, int pageSize, long cursor, int pageOffset)
        {
            this.Key = key;
            this.Scan = new ScanMessage(fieldPattern, pageSize, cursor, pageOffset);
        }
    }
    public class HashIncrementMessage : RedisMessageWrapper<HashEntry, long>
    {
        public HashIncrementMessage(RedisKey key, HashEntry HashEntry)
        {
            this.Key = key;
            this.Value = HashEntry;
        }
    }

    public class HashFieldsMessage : RedisMessageWrapper<RedisValue, RedisValue[]>
    {
        public HashFieldsMessage(RedisKey key)
        {
            this.Key = key;
        }
    }

    public class HashValuesMessage : RedisMessageWrapper<RedisValue, RedisValue[]>
    {
        public HashValuesMessage(RedisKey key)
        {
            this.Key = key;
        }
    }

    public class HashLengthMessage : RedisMessageWrapper<RedisValue, long>
    {
        public HashLengthMessage(RedisKey key)
        {
            this.Key = key;
        }
    }

    #endregion

    #region List

    public class EMListValue
    {
        public RedisValue Pivot { get; set; }
        public RedisValue InsertValue { get; set; }
        public long FirstIndex { get; set; }
        public long SecondIndex { get; set; }

        public RedisValue Value { get; set; }
        public long Count { get; set; }
    }

    public class ListGetMessage : RedisMessageWrapper<int, RedisValue>
    {
        public ListGetMessage(RedisKey key, int value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class ListInsertAfterMessage : RedisMessageWrapper<EMListValue, long>
    {
        public ListInsertAfterMessage(RedisKey key, RedisValue value, string afterValue)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.Pivot = value;
            this.Value.InsertValue = afterValue;
        }
    }
    public class ListInsertBeforeMessage : RedisMessageWrapper<EMListValue, long>
    {
        public ListInsertBeforeMessage(RedisKey key, RedisValue value, RedisValue afterValue)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.Pivot = value;
            this.Value.InsertValue = afterValue;
        }
    }
    public class ListLeftPopMessage : RedisMessageWrapper<RedisValue, RedisValue>
    {
        public ListLeftPopMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class ListLeftPushMessage : RedisMessageWrapper<RedisValue, long>
    {
        public ListLeftPushMessage(RedisKey key, RedisValue value, When when)
        {
            this.Key = key;
            this.Value = value;
            this.When = when;
        }
    }
    public class ListLengthMessage : RedisMessageWrapper<RedisValue, long>
    {
        public ListLengthMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class ListRangeMessage : RedisMessageWrapper<EMListValue, RedisValue[]>
    {
        public ListRangeMessage(RedisKey key, long startIndex, long endIndex)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.FirstIndex = startIndex;
            this.Value.SecondIndex = endIndex;
        }
    }
    public class ListRightPopMessage : RedisMessageWrapper<RedisKey, RedisValue>
    {
        public ListRightPopMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class ListRightPushMessage : RedisMessageWrapper<RedisValue, long>
    {
        public ListRightPushMessage(RedisKey key, RedisValue value, When when)
        {
            this.Key = key;
            this.Value = value;
            this.When = when;
        }
    }
    public class ListSetByIndexMessage : RedisMessageWrapper<EMListValue, bool>
    {
        public ListSetByIndexMessage(RedisKey key, RedisValue value, long index)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.FirstIndex = index;
            this.Value.InsertValue = value;
        }
    }
    public class ListTrimMessage : RedisMessageWrapper<EMListValue, bool>
    {
        public ListTrimMessage(RedisKey key, long startIndex, long stopIndex)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.FirstIndex = startIndex;
            this.Value.SecondIndex = stopIndex;
        }
    }
    public class LockTakeMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public LockTakeMessage(RedisKey key, RedisValue value, TimeSpan? expiredTime)
        {
            this.Key = key;
            this.Value = value;
            this.ExpiredTime = expiredTime;
        }
    }
    public class LockQueryMessage : RedisMessageWrapper<RedisValue, RedisValue>
    {
        public LockQueryMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class LockReleaseMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public LockReleaseMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }

    public class RedisInfoMessage : RedisMessageWrapper<string, string>
    {
        public RedisInfoMessage(string value)
        {
            this.Value = value;
        }
    }
    public class ClientListMessage : RedisMessageWrapper<string, ClientInfo[]>
    {
        public ClientListMessage(string value)
        {
            this.Value = value;
        }
    }
    public class ListRemoveMessage : RedisMessageWrapper<EMListValue, long>
    {
        public ListRemoveMessage(RedisKey key, RedisValue value, long count)
        {
            this.Key = key;
            this.Value = new EMListValue();
            this.Value.Value = value;
            this.Value.Count = count;
        }
    }

    #endregion

    #region Set

    public class SetAddMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public SetAddMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class SetAddArrayMessage : RedisMessageWrapper<RedisValue[], long>
    {
        public SetAddArrayMessage(RedisKey key, RedisValue[] value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class EMSetValue
    {
        public SetOperation Operation { get; set; }
        public RedisKey Source { get; set; }
        public RedisKey First { get; set; }
        public RedisKey Second { get; set; }
        public RedisKey Destination { get; set; }
        public RedisKey[] Keys { get; set; }
        public RedisValue Value { get; set; }
    }
    public class SetCombineMessage : RedisMessageWrapper<EMSetValue, RedisValue[]>
    {
        public SetCombineMessage(SetOperation operation, RedisKey first, RedisKey second)
        {
            this.Key = first;
            this.Value = new EMSetValue();
            this.Value.Operation = operation;
            this.Value.First = first;
            this.Value.Second = second;
        }
    }
    public class SetCombineArrayMessage : RedisMessageWrapper<EMSetValue, RedisValue[]>
    {
        public SetCombineArrayMessage(SetOperation operation, RedisKey[] keys)
        {
            this.Value = new EMSetValue();
            this.Value.Operation = operation;
            this.Value.Keys = keys;
        }
    }
    public class SetCombineAndStoreArrayMessage : RedisMessageWrapper<EMSetValue, long>
    {
        public SetCombineAndStoreArrayMessage(SetOperation operation, RedisKey destination, RedisKey[] keys)
        {
            this.Key = destination;
            this.Value = new EMSetValue();
            this.Value.Operation = operation;
            this.Value.Destination = destination;
            this.Value.Keys = keys;
        }
    }
    public class SetCombineAndStoreMessage : RedisMessageWrapper<EMSetValue, long>
    {
        public SetCombineAndStoreMessage(SetOperation opeation, RedisKey destination, RedisKey first, RedisKey second)
        {
            this.Key = destination;
            this.Value = new EMSetValue();
            this.Value.Operation = opeation;
            this.Value.Destination = destination;
            this.Value.First = first;
            this.Value.Second = second;
        }
    }
    public class SetContainsMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public SetContainsMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class SetLengthMessage : RedisMessageWrapper<RedisKey, long>
    {
        public SetLengthMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class SeMembersMessage : RedisMessageWrapper<RedisKey, RedisValue[]>
    {
        public SeMembersMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class SetMoveMessage : RedisMessageWrapper<EMSetValue, bool>
    {
        public SetMoveMessage(RedisKey source, RedisKey destination, RedisValue value)
        {
            this.Key = source;
            this.Value = new EMSetValue();
            this.Value.Source = source;
            this.Value.Destination = destination;
            this.Value.Value = value;
        }
    }
    public class SetPopMessage : RedisMessageWrapper<RedisKey, RedisValue>
    {
        public SetPopMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class SetRandomMemeberMessage : RedisMessageWrapper<RedisKey, RedisValue>
    {
        public SetRandomMemeberMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class SetRandomMembersMessage : RedisMessageWrapper<long, RedisValue[]>
    {
        public SetRandomMembersMessage(RedisKey key, long count)
        {
            this.Key = key;
            this.Value = count;
        }
    }
    public class SetRemoveArrayMessage : RedisMessageWrapper<RedisValue[], long>
    {
        public SetRemoveArrayMessage(RedisKey key, RedisValue[] values)
        {
            this.Key = key;
            this.Value = values;
        }
    }
    public class SetRemoveMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public SetRemoveMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }

    #endregion

    #region SortedSet

    public class SortedSetValue
    {
        public RedisValue Member { get; set; }
        public double Score { get; set; }
        public double IncreOrDecreValue { get; set; }
        public double Min { get; set; }
        public double Max { get; set; }
        public Exclude Exclude { get; set; }

        public long Start { get; set; }
        public long Stop { get; set; }
        public Order Order { get; set; }

        public double ScoreStart { get; set; }
        public double ScoreStop { get; set; }
        public long Skip { get; set; }
        public long Take { get; set; }
    }

    public class SortedSetAddMessage : RedisMessageWrapper<SortedSetValue, bool>
    {
        public SortedSetAddMessage(string key, string member, double score, When when)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.Member = member;
            this.Value.Score = score;
            this.When = when;
        }
    }
    public class SortedSetDecrementMessage : RedisMessageWrapper<SortedSetValue, double>
    {
        public SortedSetDecrementMessage(string key, string member, double value)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.Member = member;
            this.Value.IncreOrDecreValue = value;
        }
    }
    public class SortedSetIncrementMessage : RedisMessageWrapper<SortedSetValue, double>
    {
        public SortedSetIncrementMessage(string key, string member, double value)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.Member = member;
            this.Value.IncreOrDecreValue = value;
        }
    }
    public class SortedSetLengthMessage : RedisMessageWrapper<SortedSetValue, long>
    {
        public SortedSetLengthMessage(string key, double min, double max, Exclude exclude)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.Min = min;
            this.Value.Max = max;
            this.Value.Exclude = exclude;
        }
    }
    public class SortedSetRangeByRankMessage : RedisMessageWrapper<SortedSetValue, RedisValue[]>
    {
        public SortedSetRangeByRankMessage(string key, long start, long stop, Order order)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.Start = start;
            this.Value.Stop = stop;
            this.Value.Order = order;
        }
    }
    public class SortedSetRangeByScoreMessage : RedisMessageWrapper<SortedSetValue, RedisValue[]>
    {
        public SortedSetRangeByScoreMessage(string key, double scoreStart, double scoreStop, Exclude exclude, Order order, long skip = 0, long take = -1)
        {
            this.Key = key;
            this.Value = new SortedSetValue();
            this.Value.ScoreStart = scoreStart;
            this.Value.ScoreStop = scoreStop;
            this.Value.Order = order;
            this.Value.Exclude = exclude;
            this.Value.Skip = skip;
            this.Value.Take = take;
        }
    }
    public class SortedSetRemoveMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public SortedSetRemoveMessage(string key, string member)
        {
            this.Key = key;
            this.Value = member;
        }
    }

    #endregion

    #region HyperLogLog

    public class HyperLogLogAddMessage : RedisMessageWrapper<RedisValue, bool>
    {
        public HyperLogLogAddMessage(RedisKey key, RedisValue value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class HyperLogLogAddArrayMessage : RedisMessageWrapper<RedisValue[], bool>
    {
        public HyperLogLogAddArrayMessage(RedisKey key, RedisValue[] value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
    public class HyperLogLogLengthMessage : RedisMessageWrapper<RedisValue, long>
    {
        public HyperLogLogLengthMessage(RedisKey key)
        {
            this.Key = key;
        }
    }
    public class HyperLogLogLengthArrayMessage : RedisMessageWrapper<RedisKey[], long>
    {
        public HyperLogLogLengthArrayMessage(RedisKey[] keys)
        {
            this.Key = keys.First();
            this.Value = keys;
        }
    }
    public class HyperLogLogMergeMessage : RedisMessageWrapper<HyperLogLogMergeValue, bool>
    {
        public HyperLogLogMergeMessage(RedisKey destination, RedisKey first, RedisKey second)
        {
            var mergeValue = new HyperLogLogMergeValue();
            mergeValue.Destination = destination;
            mergeValue.First = first;
            mergeValue.Second = second;
            this.Key = destination;
            this.Value = mergeValue;
        }
    }
    public class HyperLogLogMergeArrayMessage : RedisMessageWrapper<HyperLogLogMergeValue, bool>
    {
        public HyperLogLogMergeArrayMessage(RedisKey destination, RedisKey[] sourceKeys)
        {
            var mergeValue = new HyperLogLogMergeValue();
            mergeValue.Destination = destination;
            mergeValue.SourceKeys = sourceKeys;
            this.Key = destination;
            this.Value = mergeValue;
        }
    }
    public class HyperLogLogMergeValue
    {
        public RedisKey Destination { get; set; }
        public RedisKey First { get; set; }
        public RedisKey Second { get; set; }
        public RedisKey[] SourceKeys { get; set; }
    }

    #endregion

    #region Bitmaps

    public class BitValue
    {
        public Bitwise Operation { get; set; }
        public RedisKey Destination { get; set; }
        public RedisKey First { get; set; }
        public RedisKey Second { get; set; }
        public RedisKey[] Keys { get; set; }

        public bool Bit { get; set; }
        public long Offset { get; set; }

        public long Start { get; set; }
        public long End { get; set; }
    }
    public class StringBitCountMessage : RedisMessageWrapper<BitValue, long>
    {
        public StringBitCountMessage(RedisKey key, long start, long end)
        {
            var bitValue = new BitValue
            {
                Start = start,
                End = end
            };
            this.Key = key;
            this.Value = bitValue;
        }
    }
    public class StringBitOperationMessage : RedisMessageWrapper<BitValue, long>
    {
        public StringBitOperationMessage(RedisKey destination, Bitwise operation, RedisKey first, RedisKey second)
        {
            var bitValue = new BitValue
            {
                Operation = operation,
                Destination = destination,
                First = first,
                Second = second
            };
            this.Key = destination;
            this.Value = bitValue;
        }
    }
    public class StringBitOperationArrayMessage : RedisMessageWrapper<BitValue, long>
    {
        public StringBitOperationArrayMessage(RedisKey destination, Bitwise operation, RedisKey[] keys)
        {
            var bitValue = new BitValue
            {
                Operation = operation,
                Destination = destination,
                Keys = keys
            };
            this.Key = destination;
            this.Value = bitValue;
        }
    }
    public class StringBitPositionMessage : RedisMessageWrapper<BitValue, long>
    {
        public StringBitPositionMessage(RedisKey key, bool bit, long start, long end)
        {
            var bitValue = new BitValue
            {
                Bit = bit,
                Start = start,
                End = end
            };
            this.Key = key;
            this.Value = bitValue;
        }
    }
    public class StringGetBitMessage : RedisMessageWrapper<long, bool>
    {
        public StringGetBitMessage(RedisKey key, long offset)
        {
            this.Key = key;
            this.Value = offset;
        }
    }
    public class StringSetBitMessage : RedisMessageWrapper<BitValue, bool>
    {
        public StringSetBitMessage(RedisKey key, bool bit, long offset)
        {
            var bitValue = new BitValue
            {
                Bit = bit,
                Offset = offset
            };
            this.Key = key;
            this.Value = bitValue;
        }
    }

    #endregion
}
